#include "Partitioning.h"
#include "Player.h"
#include "Ball.h"

void Partition::Init(vec3 size, int rows, int cols)
{
	this->rows = rows;
	this->cols = cols;

	// Size of every Grid
	vec3 GridSize = vec3(size.x / rows, Grid::Max_Y_Bound, size.z / cols);

	// Position of the first Grid
	vec3 firstpos = (size - GridSize) / 2;
	firstpos.y = 0;

	GLuint id1 = vbo.Begin(GL_LINES);

	for(int i = 0; i < rows; ++i)
	{
		for(int j = 0; j < cols; ++j)
		{
			vec3 GridPos = firstpos - vec3(GridSize.x * i, 0, GridSize.z * j);
			grids.push_back( new Grid(GridPos, GridSize) );
			grids.back()->row = i;
			grids.back()->col = j;
			grids.back()->player = player;
			GridParent.AddChild( grids.back() );

			vec3 min = GridPos - GridSize/2, max = GridPos + GridSize/2;
			vbo.AddVertex(min.x, GridHeight, min.z);
			vbo.AddVertex(min.x, GridHeight, max.z);

			vbo.AddVertex(min.x, GridHeight, max.z);
			vbo.AddVertex(max.x, GridHeight, max.z);

			vbo.AddVertex(max.x, GridHeight, max.z);
			vbo.AddVertex(max.x, GridHeight, min.z);

			vbo.AddVertex(max.x, GridHeight, min.z);
			vbo.AddVertex(min.x, GridHeight, min.z);
		}
	}

	vbo.SetColor(id1, 1, 1, 0, 0.2f);
	vbo.End(GL_STATIC_DRAW);
}

enum { NORTH = 0, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST };
void Partition::Update(float delta)
{
//	for(int i = 0; i < grids.size(); ++i)
//	{
//		grids[i]->Update(delta);
		//Grid* grid = grids[i];
		//if(!grid->isNodeInGrid(player))
		//{
		//	grid->alpha = 0.5f;
		//	continue;
		//}

		//grid->alpha = 0.0f;
		//int row = grid->row, col = grid->col;

		//Grid *surrounding[8];
		//for(int distance = 1; distance < MediumDistance; distance++)
		//{
		//	surrounding[NORTH]		= GetGrid(row, col+distance);
		//	surrounding[SOUTH]      = GetGrid(row, col-distance);
		//	surrounding[EAST]       = GetGrid(row+distance, col);
		//	surrounding[WEST]       = GetGrid(row-distance, col);
		//	surrounding[NORTHEAST]	= GetGrid(row+distance, col+distance);
		//	surrounding[NORTHWEST]  = GetGrid(row-distance, col+distance);
		//	surrounding[SOUTHEAST]  = GetGrid(row+distance, col-distance);
		//	surrounding[SOUTHWEST]  = GetGrid(row-distance, col-distance);

		//	vec3 newColor;
		//	if(distance < NearDistance) newColor = NearColor;
		//	else if(distance < MediumDistance) newColor = MediumColor;
		//	else newColor = FarColor;

		//	for(int j = 0; j < 8; ++j)
		//	{
		//		if(	surrounding[j] && surrounding[j]->alpha > 0.0f &&
		//			surrounding[j]->color != NearColor)
		//		{
		//			surrounding[j]->color = newColor;
		//		}
		//	}
		//}
//	}
}

Grid* Partition::GetGrid(int row, int col)
{
	if(	row > rows || col > cols ||
		row * col >= grids.size() ||
		row < 0 || col < 0) return NULL;

	for(int i = 0; i < grids.size(); ++i)
		if(	grids[i]->row == row &&
			grids[i]->col == col)
			return grids[i];

	return NULL;
}

void Partition::Draw(void)
{
	if(!bDraw) return;

	glPushAttrib(GL_ENABLE_BIT);
		glDisable(GL_LIGHTING);
		glEnable(GL_CULL_FACE);
		glEnable(GL_BLEND);
		glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );

		vbo.Draw();

		for(int i = 0; i < grids.size(); ++i)
		{
			glPushMatrix();
				if(balls->children)
				{
					for(ListIter it = balls->children->begin(); it != balls->children->end(); ++it)
					{
						if( grids[i]->isNodeInGrid(*it) )
						{
							(*it)->detail_level = grids[i]->detail_level;
						}
					}
				}

				grids[i]->Update(1);
				glTranslatef( grids[i]->wPos.x, 0, grids[i]->wPos.z );
				grids[i]->Draw();
			glPopMatrix();
		}

		glDisable(GL_BLEND);

	glPopAttrib();
}